package com.liumo.utils;

import com.liumo.domain.*;
import com.liumo.domain.intface.BinaryOperation;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/**
 *  实体类放在domain包下
 *  本工具类用于处理应用逻辑
 *  --TODO
 *  现在新的任务，引入教师类，和学生类
 *  使用map集合存储教师和学生信息，Map<Integer, String>，String 对象存储该账号对应的文件夹
 *  文件夹下对应多个文件，分别为序列化在硬盘中的学生/教师对象
 *  和老师包下的题目
 */
public class BinaryOperationUtil {
    protected static int one;
    protected static int two;
    protected static int numer = 10;  // 生成的题目数量
    protected static int count = 0;
    protected static ArrayList<BinaryOperation> adds = new ArrayList<>();
    protected static ArrayList<BinaryOperation> lows = new ArrayList<>();
    protected static Random random = new Random();
    private static final String practicalAddsFilePath = "D:\\zawenjian\\personList\\teacher\\practical\\adds.ad";
    private static final String practicalLowsFilePath = "D:\\zawenjian\\personList\\teacher\\practical\\lows.lo";

    // 教师用户登录使用的模块
    public static void teacherStart(Scanner scan, Teacher teacher){
        System.out.println("----------选择你想选择的模式'1'混合加减，'2'加法 '3'减法 '4/test'手动输入测试 '5'生成习题---------" );
        while (true) {
            String flog = scan.next();
            switch (flog) {
                case "1":
                    mix();
                    soutBinaryOperation();
                    break;
                case "2":
                    addition();
                    soutBinaryOperation();
                    break;
                case "3":
                    subtraction();
                    soutBinaryOperation();
                    break;
                case "4":
                case "test":
                    test(scan);
                    break;
                case "5":
                    writeBinary(scan);
                    break;
                case "0":
                case "exit":
                    System.out.println("~~~~~~正在退出~~~~~~");
                    return;
            }
            System.out.println();
            System.out.println("-----退出'0/exit'或继续选择其他模式'1'混合加减，'2'加法 '3'减法 '4/test'手动输入测试 '5'生成习题-------");
        }
    }
    // 学生用户登录使用的模块
    public static void studentStart(Scanner scan, Student student){
        System.out.println("----------选择你想选择的模式'1'混合加减，'2'加法 '3'减法 '4'作业模式---------" );
        while (true) {
            String flog = scan.next();
            switch (flog) {
                case "1":
                    mix();
                    OperationBase.practice(adds, lows, scan);
                    clearPractical();
                    break;
                case "2":
                    addition();
                    OperationBase.practice(adds, lows, scan);
                    clearPractical();
                    break;
                case "3":
                    subtraction();
                    OperationBase.practice(adds, lows, scan);
                    clearPractical();
                    break;
                case "4":
                    readFromFile();
                    OperationBase.practice(adds, lows, scan);
                    clearPractical();
                    break;
                case "0":
                case "exit":
                    System.out.println("~~~~~~正在退出~~~~~~");
                    return;
            }
            System.out.println();
            System.out.println("-----退出'0/exit'或继续选择其他模式'1'混合加减，'2'加法 '3'减法 '4'习题模式-------");
        }

    }

    private static void writeBinary(Scanner scan) {
        int model;
        System.out.println("----------输入你想生成式子的模式'1'混合加减，'2'加法 '3'减法 '4'手动输入 ---------");
        model = scan.nextInt();
        switch (model) {
            case 1:
                System.out.print("生成式子的次数：");
                numer = scan.nextInt();
                mix();
                writeToFile();
                soutBinaryOperation();
                numer = 10;
                break;
            case 2:
                System.out.print("生成式子的次数：");
                numer = scan.nextInt();
                addition();
                writeToFile();
                soutBinaryOperation();
                numer = 10;
                break;
            case 3:
                System.out.print("生成式子的次数：");
                numer = scan.nextInt();
                subtraction();
                writeToFile();
                soutBinaryOperation();
                numer = 10;
                break;
            case 4:
                hand(scan);
                soutAddtion();
                soutSubtion();
                writeToFile();
                break;
            case 0:
                return;
            }
    }
    // 将生成的式子分别存放在adds/lows文件中
    private static void writeToFile(){
       try(
               ObjectOutputStream aoos = new ObjectOutputStream(new FileOutputStream(practicalAddsFilePath));
               ObjectOutputStream loos = new ObjectOutputStream(new FileOutputStream(practicalLowsFilePath));
               ){
           System.out.println();
           if (adds.isEmpty()) {
               System.out.println("adds is null");
           }
           aoos.writeObject(adds);
           System.out.println("adds.ad习题写入完毕");
           loos.writeObject(lows);
           System.out.println("lows.lo习题写入完毕");
       }catch (Exception e) {
           e.printStackTrace();
       }
//       }finally {
//           adds.clear();
//           lows.clear();
//       }
    }
    private static void readFromFile(){
        try(
                ObjectInputStream aoos = new ObjectInputStream(new FileInputStream(practicalAddsFilePath));
                ObjectInputStream loos = new ObjectInputStream(new FileInputStream(practicalLowsFilePath));
        ){
            System.out.println();
            adds = (ArrayList<BinaryOperation>) aoos.readObject();
            if (adds.isEmpty())
                System.out.println("adds is null");
            System.out.println("adds.ad习题读入完毕");
//            for (BinaryOperation bo: adds){
//                System.out.println(bo.getBinaryOperationStr());
//            }
            lows = (ArrayList<BinaryOperation>) loos.readObject();
            System.out.println("lows.lo习题读入完毕");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void start(Scanner scan) {
        while (true) {
            String flog = scan.next();
            switch (flog) {
                case "1":
                    mix();
                    break;
                case "2":
                    addition();
                    break;
                case "3":
                    subtraction();
                    break;
                case "4":
                case "test":
                    test(scan);
                    break;
                case "0":
                case "exit":
                    System.out.println("~~~~~~正在退出~~~~~~");
                    return;
            }
            System.out.println();
            System.out.println("-----退出'0/exit'或继续选择其他模式'1'混合加减，'2'加法 '3'减法 '4/test'手动输入测试-------");
        }
    }

    // 混合加减法运算
    public static void mix() {
        int i = 0;
        while (i < numer) {
            BinaryOperation operation;
            one = random.nextInt( 100);
            two = random.nextInt( 100);

            // 随机选择加法或减法
            if (random.nextInt() % 2 == 1) {
                operation = new SubtractionOperation(); // 创建减法对象
            } else {
                operation = new AdditionOperation(); // 创建加法对象
            }

            operation.setOperands(one, two); // 设置操作数
            operation.createBinaryOperation(); // 生成运算式

            if (adds.contains(operation) || lows.contains(operation)) {
                continue;
            }

            // 根据运算符将式子分类
            if (operation instanceof AdditionOperation) {
                adds.add(operation);
            } else {
                lows.add(operation);
            }
            i++;
        }
    }

    // 加法运算
    public static void addition() {
        int i = 0;
        while (i < numer) {
            one = random.nextInt(100);
            two = random.nextInt(100);
            BinaryOperation operation = new AdditionOperation();
            operation.setOperands(one, two);
            operation.createBinaryOperation();
            if (adds.contains(operation)) {
                continue;
            }
            adds.add(operation);
            i++;
        }
    }

    // 减法运算
    public static void subtraction() {
        int i = 0;
        while (i < numer) {
            one = random.nextInt(100);
            two = random.nextInt(100);
            BinaryOperation operation = new SubtractionOperation();
            operation.setOperands(one, two);
            operation.createBinaryOperation();
            if (lows.contains(operation)) {
                continue;
            }
            lows.add(operation);
            i++;
        }
    }

    // 加法输出
    public static void soutAddtion() {
        System.out.println("-----------------下面是加法计算------------------");
        for (BinaryOperation bo : adds) {
            if (count == 6) {
                System.out.println();
                count = 0;
            }
                System.out.print(bo.getBinaryOperationStr());

            count++;
        }
        System.out.println();
        count = 0;
        adds.clear();
    }

    // 减法输出
    public static void soutSubtion() {
        System.out.println("-----------------下面是减法计算------------------");
        for (BinaryOperation bo : lows) {
            if (count == 6) {
                System.out.println();
                count = 0;
            }
                System.out.print(bo.getBinaryOperationStr());
            count++;
        }
        count = 0;
        lows.clear();
    }

    // 手动输入测试
    public static void hand(Scanner scan) {
        while (true) {
            try {
                System.out.print("(输入000测试输入退出)输入第一个数： ");
                String str = scan.next();
                if (str.equals("000"))
                    break;
                one = Integer.valueOf(str);
                System.out.print("输入符号： ");
                String input = scan.next();
                BinaryOperation operation = null;
                if (input.contains("-")) {
                    operation = new SubtractionOperation();
                } else if (input.contains("+")) {
                    operation = new AdditionOperation();
                } else {
                    throw new Exception("输入符号应为+/-");
                }
                System.out.print("输入第二个数： ");
                two = scan.nextInt();
                System.out.print("输入结果： ");
                int resultT = scan.nextInt();

                operation.setOperands(one, two);
                operation.createBinaryOperation();

                if (operation.equals(one + " " + input + " " + two + " = " + resultT)) {
                    System.out.println("输入正确！");
                } else {
                    throw new Exception("结果有误");
                }

            } catch (Exception e) {
                System.out.println(e.getMessage());
                System.out.println("----------输入有误请重新输入-------------");
            }
        }
    }
    // 将式子进行输出在控制面板上
    public static void soutBinaryOperation(){
        if (!adds.isEmpty())
            soutAddtion();
        if (!lows.isEmpty())
            soutSubtion();
        clearPractical();
    }
    // 测试功能
    public static void test(Scanner scan) {
        int model = 0;
        while (true) {
            System.out.println("----------输入你想测试的模式'1'混合加减，'2'加法 '3'减法 '4'手动输入测试 ---------");
            model = scan.nextInt();
            switch (model) {
                case 1:
                    System.out.print("生成式子的次数：");
                    numer = scan.nextInt();
                    mix();
                    numer = 10;
                    clearPractical();
                    break;
                case 2:
                    System.out.print("生成式子的次数：");
                    numer = scan.nextInt();
                    addition();
                    numer = 10;
                    clearPractical();
                    break;
                case 3:
                    System.out.print("生成式子的次数：");
                    numer = scan.nextInt();
                    subtraction();
                    numer = 10;
                    clearPractical();
                    break;
                case 4:
                    hand(scan);
                    break;
                case 0:
                    return;
            }
            System.out.println();
        }
    }
    public static void clearPractical(){
        adds.clear();
        lows.clear();
    }
}
